
/* -----------------
* brief 
* 1. this is code gen by tools
*/

package service

import (
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/mjiulee/lego"
	"saas_sys_base/common"
	"time"
)
import . "saas_sys_base/modules/user/models"

type WebUserService struct {
	UserService
	appTenantUserRelService AppTenantUserRelService
	appTenantRelService AppTenantRelService

	// add your model here
	tbWebUser WebUser
}

var _ UserServiceInterface = (*WebUserService)(nil)

func (t* WebUserService)ListWebUser(keyword string,page,psize int) ([]map[string]string, int64, error) {
	// 业务查询
	queryMap := map[string]interface{}{
		"table":  map[string]string{"table": "tb_web_user", "alias": "t1"},
		"fields": []string{"t1.*"},
		"join": []map[string]string{
			// map[string]string{"table": "tb_xx as t2", "on": "t2.xid = t1.id"},
		},
		"where": []lego.QMapWhereField{
			//{"t1.if_del", "=", 0, "AND", false},
		},
		"search": map[string]string{
			//"t1.id": req.Keyword,
		},
		"orders": []string{"t1.id asc"},
		"page": map[string]int{
			"page":  page,
			"psize": psize,
		},
	}
	return lego.QueryListByMap(queryMap)
}

/* 根据id获取记录
 * -----------------
 */
func (t* WebUserService) GetWebUserById(id int64) *WebUser {
	return t.tbWebUser.RecodeById(id)
}

/* 添加
 * -----------------
 */
func (t* WebUserService) SaveWebUser(item2add *WebUser) bool {
	return t.tbWebUser.AddRecode(item2add)
}

/* 删除(硬删除)*/
func (t* WebUserService) DelWebUserById(id int64) bool {
	return t.tbWebUser.DelRecodeById(id)
}

/* 更新
 * -----------------*/
func (t* WebUserService) UpdateWebUser(rc *WebUser) bool {
	return t.tbWebUser.UpdateRecode(rc)
}

func (t *WebUserService) userLogin(account string, password string) (user *WebUser, tokenString string, err error) {

	dbuser := t.tbWebUser.RecodeByAccount(account/*, weappid*/)
	if dbuser == nil { // 新用户
	    return nil, "", errors.New(common.ERR_MSG_USER_NO_EXIST)
	}

	if dbuser.Password != password {
		return nil, "", errors.New(common.ERR_MSG_PASSWORD_NOT_CORRECT)
	}

	return dbuser, tokenString, nil
}

func (t *WebUserService) createAccount(account string, password string) (user *WebUser, tokenString string, err error) {
	user = t.tbWebUser.RecodeByAccount(account/*, weappid*/)
	if user == nil {
		user = new(WebUser)
		user.Account = account
		user.Password = password
		user.Status = common.STATE_YES

		if false == t.tbWebUser.AddRecode(user) {
			return nil, "", errors.New("注册失败")
		}
	} else {
		return nil, "", errors.New("注册失败(注册用户名已存在)")
	}

	tokenString, err = t.generateToken(user)
	if err != nil {
		return nil, "", err
	}

	return user, tokenString, nil
}

func (t *WebUserService) deleteAccount(account string) (err error) {
	isErr := t.tbWebUser.DelRecodeByAccount(account/*, weappid*/)
	if isErr {
		errors.New(common.ERR_MSG_DELETE_ACCOUNT_FAIL)
	}

	return nil
}


func (t *WebUserService) generateToken(user *WebUser) (tokenString string, err error) {
	if user == nil {
		return "", errors.New("token生成失败, 用户信息无效")
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"uid": fmt.Sprintf("%d", user.Id), // 这个地方，他会转成float64，很奇葩
		"exp": time.Now().Add(time.Hour * 24).Unix(),
	})

	tokenString, err = token.SignedString([]byte(lego.TokenSecretKey()))
	if err != nil {
		return "", errors.New("token生成失败")
	}

	return tokenString, nil
}


//自定义函数


/*func (t *WebUserService) CreateAccount(whoAppTenant common.Who, account string, password string) (*WebUser, error) {
	webUser, _, err := t.createAccount(account, password) //webuser表里面不区分是哪个微应用，平台唯一账户名
	if err != nil {
		return nil, err
	}
	return webUser, nil
}*/

func (t *WebUserService) CreateAccount(whoAppTenant common.Who, account string, password string) (user *LoginUser, tokenString string, err error){

	//TODO 这里要做session
	webUser, _, err := t.createAccount(account, password) //webuser表里面不区分是哪个微应用，平台唯一账户名
	if err != nil {
		return nil, "", err
	}
	sysUser, err := t.webUserLogin(webUser.Id) //这里为了给每个user维护一个系统内唯一的用户记录，用户在多个租户处登录，这里也只有一个用户记录
	if err != nil {
		//t.deleteAccount(account) //TODO 后面改为事物
		return nil, "", err
	}

	//登录后，使用得到的Uid，组合成一个表示user的who对象
	whoUser := common.NewWho(whoAppTenant.TenantId, whoAppTenant.MiniAppId, sysUser.Id)
	_, userRelTokenString, err := t.appTenantUserRelService.userLogin(*whoUser/*MiniAppId, tid, sysUser.Id*/) //这个登录就是多租户的关系表，建立appid、租户id、Uid
	if err != nil {
		//t.deleteAccount(account) //TODO 后面改为事物
		return nil, "", err
	}

	//wxTokenString = wxTokenString //暂时不需要wx token

	user = new(LoginUser)
	user.User = sysUser
	user.WebUser = webUser
	return user, userRelTokenString, nil
}


func (t *WebUserService) UserLogin(whoAppTenant common.Who, account string, password string) (user *LoginUser, tokenString string, err error) {
	webUser, _, err := t.userLogin(account, password) //webuser表里面不区分是哪个微应用，平台唯一账户名
	if err != nil {
		return  nil, "", err
	}

	sysUser, err := t.webUserLogin(webUser.Id) //这里为了给每个user维护一个系统内唯一的用户记录，用户在多个租户处登录，这里也只有一个用户记录
	if err != nil {
		return nil, "", err
	}

	//登录后，使用得到的Uid，组合成一个表示user的who对象
	whoUser := common.NewWho(whoAppTenant.TenantId, whoAppTenant.MiniAppId, sysUser.Id)
	_, userRelTokenString, err := t.appTenantUserRelService.userLogin(*whoUser/*MiniAppId, tid, sysUser.Id*/) //这个登录就是多租户的关系表，建立appid、租户id、Uid
	if err != nil {
		return nil, "", err
	}

	//wxTokenString = wxTokenString //暂时不需要wx token

	user = new(LoginUser)
	user.User = sysUser
	user.WebUser = webUser
	return user, userRelTokenString, nil
}

func (t *WebUserService) webUserLogin(webUid int64) (sysUser *User, err error) {
	//查看是否注册过，如果没有
	var user *User
	user = t.tbUser.RecodeByWebUid(webUid)
	if user == nil {
		var item2add User
		item2add.WebUid = webUid
		if false == t.tbUser.AddRecode(&item2add) {
			return nil, errors.New("userLogin failed in UserService userLogin")
		}

		user = &item2add
	}
	return user, nil
}

func (t *WebUserService) ThirdLogin(WebUid int64) (UnionUser *User, err error) {
	//查看是否注册过，如果没有
	var user *User
	user = t.tbUser.RecodeByWebUid(WebUid)

	if user == nil {
		var item2add User
		item2add.WebUid = WebUid
		if false == t.tbUser.AddRecode(&item2add) {
			return nil, errors.New("ThirdLogin failed in WebUserService ThirdLogin")
		}

		user = &item2add
	}
	return user, nil
}

//创建租户账户
func (t *WebUserService) CreateTenantAccount(whoAppTenant common.Who, account string, password string) (user *LoginUser, tokenString string, err error){

	//TODO 这里要做session
	webUser, _, err := t.createAccount(account, password) //webuser表里面不区分是哪个微应用，平台唯一账户名
	if err != nil {
		return nil, "", err
	}
	sysUser, err := t.webUserLogin(webUser.Id) //这里为了给每个user维护一个系统内唯一的用户记录，用户在多个租户处登录，这里也只有一个用户记录
	if err != nil {
		//t.deleteAccount(account) //TODO 后面改为事物
		return nil, "", err
	}

	//登录后，使用得到的Uid，组合成一个表示user的who对象
	whoUser := common.NewWho(whoAppTenant.TenantId, whoAppTenant.MiniAppId, sysUser.Id)
	_, userRelTokenString, err := t.appTenantRelService.userLogin(*whoUser/*MiniAppId, tid, sysUser.Id*/) //这个登录就是多租户的关系表，建立appid、租户id、Uid
	if err != nil {
		//t.deleteAccount(account) //TODO 后面改为事物
		return nil, "", err
	}

	//wxTokenString = wxTokenString //暂时不需要wx token

	user = new(LoginUser)
	user.User = sysUser
	user.WebUser = webUser
	return user, userRelTokenString, nil
}